<?php
declare(strict_types=1);

namespace App\Middleware;

use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Hyperf\Utils\Context;
use App\Service\Code\Normal;
use App\Service\BaseService;
use App\Model\PssModel\Manager;

class RequestCloudh5ApiMiddleware implements MiddlewareInterface
{
    //访问频率限制key
    const VISIT_FREQUENCY_KEY   = 'mbyc_cloundh5_visit_frequency_key_';
    const VISIT_LIMIT           = 200;
    const VISTI_EXPIRE          = 60;
    protected $except = [
        '/Cloudh5/AdminUserLogin/UserLogin',//用户登录
    ];
    
    /**
     * @var ContainerInterface
     */
    protected $container;

    /**
     * @var RequestInterface
     */
    protected $request;

    /**
     * @var HttpResponse
     */
    protected $response;

    /**
     * @var sys_user_id
     */
    protected $sys_user_id = 137;

    public function __construct(ContainerInterface $container, HttpResponse $response, RequestInterface $request)
    {
        $this->container = $container;
        $this->response = $response;
        $this->request = $request;
    }

    //中间介质处理
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $param = $this->request->all();
        $token = $this->request->header('token');
        $token = $token ? $token : ($param['token']??'');
        $server_param = $request->getServerParams();
        $path_info = $server_param['path_info']??'';
        $server_param = [
            'ip'        => getIp(),
            'token'     => $token,
        ];
        $res = $this->_checkIsLogin($server_param);
        if( $res['code'] != Normal::SUC  && !in_array($path_info,$this->except)) {
            return $this->response->json($res);
        }
        // 将新的请求对象设置到上下文中
        $body = array_merge([
            'manager' => isset($res['data']) ? $res['data'] : [] ,
            'body'  => $param
        ]);
        $request = $request->withAttribute('param',$body);
        Context::set(RequestInterface::class, $request);
        return $handler->handle($request);
    }
    
    /**
     * 检查登录状态
     */
    protected function _checkIsLogin($server_param)
    {
        //检查访问频率
        $getIp = $server_param['ip'];
        /* if( !BaseService::instance()->visitFrequency(self::VISIT_FREQUENCY_KEY.$getIp,self::VISTI_EXPIRE,self::VISIT_LIMIT) ) {
            return Normal::returnCode(Normal::FAIL,"当前IP【{$getIp}】访问过于频繁，请稍后再试");
        } */
    
        return Manager::instance()->checkLogin($server_param);
    }
}